﻿using System.ComponentModel.DataAnnotations;

namespace Utils
{
    // 通用非空验证特性 - 支持自定义错误消息，默认格式为"xxx字段必填"
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
    public class GeneralRequiredAttribute : ValidationAttribute
    {
        // 允许的默认值（对于值类型）
        public object? AllowedDefault { get; set; } = null;

        // 字段名称（用于错误消息）
        private string _displayName;

        public GeneralRequiredAttribute() : base("参数 {0} 必填") { }

        public GeneralRequiredAttribute(string errorMessage) : base(errorMessage) { }

        public override string FormatErrorMessage(string name)
        {
            // 如果没有显式设置错误消息，使用默认格式
            if (string.IsNullOrEmpty(ErrorMessage) && string.IsNullOrEmpty(ErrorMessageResourceName))
            {
                return string.Format("参数 {0} 必填", GetDisplayName(name));
            }

            // 否则使用用户定义的错误消息
            return string.Format(ErrorMessageString, GetDisplayName(name));
        }

        public override bool IsValid(object value)
        {
            // 检查是否为null
            if (value == null)
                return false;

            // 获取值的类型
            Type type = value.GetType();

            // 处理字符串
            if (type == typeof(string))
                return !string.IsNullOrWhiteSpace((string)value);

            // 处理Guid
            if (type == typeof(Guid))
                return (Guid)value != Guid.Empty;

            // 处理可空Guid
            if (type == typeof(Guid?))
            {
                var nullableGuid = (Guid?)value;
                return nullableGuid.HasValue && nullableGuid.Value != Guid.Empty;
            }

            // 处理集合类型
            if (typeof(System.Collections.ICollection).IsAssignableFrom(type))
            {
                return ((System.Collections.ICollection)value).Count > 0;
            }

            // 处理值类型
            if (type.IsValueType)
            {
                object? defaultValue;

                if (AllowedDefault != null && type.IsAssignableFrom(AllowedDefault.GetType()))
                {
                    defaultValue = AllowedDefault;
                }
                else
                {
                    defaultValue = Nullable.GetUnderlyingType(type) != null
                        ? null
                        : Activator.CreateInstance(type);
                }

                return !value.Equals(defaultValue);
            }

            return true;
        }

        // 获取字段显示名称
        private string GetDisplayName(string name)
        {
            // 如果已经通过DisplayAttribute设置了名称
            if (!string.IsNullOrEmpty(_displayName))
                return _displayName;

            // 尝试从DisplayAttribute获取名称
            var context = ValidationContext ?? new ValidationContext(new object());
            var display = context.ObjectType.GetProperty(name)?
                .GetCustomAttributes(typeof(DisplayAttribute), true)
                .FirstOrDefault() as DisplayAttribute;

            return display?.Name ?? name;
        }

        // 重写IsValid方法以获取ValidationContext
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            ValidationContext = validationContext;
            _displayName = validationContext.DisplayName;

            return base.IsValid(value, validationContext);
        }

        // 存储ValidationContext用于获取字段名称
        private ValidationContext ValidationContext { get; set; }
    }
}